package ar.com.globallogic.promomr.services;

import java.util.Collection;
import java.util.HashSet;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import ar.com.globallogic.promomr.domain.AnonymousUser;
import ar.com.globallogic.promomr.domain.User;
import ar.com.globallogic.promomr.exceptions.LoginFailureException;
import ar.com.globallogic.promomr.persistance.UserRepository;

@Service
public class SecurityServiceImpl implements SecurityService{
	
	private static final Logger logger = LoggerFactory.getLogger(SecurityServiceImpl.class);
	
	private UserRepository userRepository;
	
	@Autowired
	public SecurityServiceImpl(UserRepository userRepository){
		this.userRepository = userRepository;
	}

	@Override
	public User getAuthenticatedUser() {
		Authentication auth = SecurityContextHolder.getContext().getAuthentication();
	    String userName = auth.getName();
	    List<User> users = userRepository.findByUserName(userName);
	    
	    User authenticatedUser = (users.isEmpty()) ? new AnonymousUser() : users.get(0);  
	    logger.info(String.format("Authenticated user: %s.", authenticatedUser.getUserName()));
	    
	    return authenticatedUser;
	}

	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
		try {
			logger.info(String.format("Building user details for user %s.", username));
			User domainUser = userRepository.findByUserName(username).get(0);
			
			boolean enabled = true;
			boolean accountNonExpired = true;
			boolean credentialsNonExpired = true;
			boolean accountNonLocked = true;
			
			Collection<GrantedAuthorityImpl> authorities = new HashSet<GrantedAuthorityImpl>();
			authorities.add(new GrantedAuthorityImpl("ROLE_USER"));					
			
			logger.info(String.format("User details for user %s were built.", username));
			return new org.springframework.security.core.userdetails.User(
					domainUser.getUserName(),
					domainUser.getPassword(),
					enabled,
					accountNonExpired,
					credentialsNonExpired,
					accountNonLocked,
					authorities);
			
		} catch (Exception e) {
			logger.error(String.format("User details for user %s were not built.", username));
			logger.debug("StackTrace: " + e.getStackTrace());
			throw new LoginFailureException(username);
		}
	}
}
